package com.ibm.risk.irmp.report.rest;

import com.ibm.risk.irmp.report.service.IReportContentService;
import com.ibm.risk.irmp.report.service.impl.GenericXlsxReportContentServiceImpl;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.xmlbeans.impl.common.IOUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.web.bind.annotation.*;

import java.io.*;
import java.util.Map;

@RestController
@RequestMapping("/v2/content/reports")
@Slf4j
public class ReportContentController {
    @Autowired
    Map<String, IReportContentService> reportServiceMap;

    @Autowired
    GenericXlsxReportContentServiceImpl genericReportService;

    /**
     * 生成Excel报表
     */
//    @AuditableRequestMapping(value="/report/{reportCode}/download", module = "风险信息展现>风险报告", funcation = "导出", level = "中",
//            description = "生成报表", method = RequestMethod.GET)
    @GetMapping("/{reportCode}/download")
    public void download(@PathVariable String reportCode, @RequestParam String dataDate, @RequestParam String reportBatchNo,
                         @RequestParam String branchCode, HttpServletRequest request, HttpServletResponse response) throws Exception {
        OutputStream outputStream = null;

        if (StringUtils.isEmpty(reportCode)) {
            throw new RuntimeException("请指定报表");
        }
        String reportCodeClean = reportCode.replace("-", "").replace("_", "")
                .replace("(", "").replace(")", "");
//            IReportContentService reportService = WebApplicationContextUtils.getWebApplicationContext(request.getServletContext())
//                    .getBean(reportCodeClean + "ReportService", IReportContentService.class);

        String filename = new String((reportCode + ".xlsx").getBytes("utf-8"), "iso8859-1");
        Workbook workbook = null;
        //生成Excel报表
        //cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/opt/middleware/rwa/rwa.war!/WEB-INF/classes!/templates/G4B2.xlsx
    /*
    //File templateFile = ResourceUtils.getFile("classpath:templates/" + reportCode + ".xlsx");
    ClassPathResource classPathResource = new ClassPathResource("templates/" + reportCodeClean + ".xlsx");
//            InputStream inputStream = classPathResource.getInputStream();
    //生成目标文件
//            File templateFile = File.createTempFile("template_" + System.nanoTime(), ".xlsx");
//            FileUtils.copyInputStreamToFile(inputStream, templateFile);
    */
        String tempPath = System.getProperty("java.io.tmpdir") + File.separator + "tomcat_" + System.currentTimeMillis();
        File tempFile = new File(FilenameUtils.normalize(tempPath + File.separator + filename));
        Resource resource = new DefaultResourceLoader().getResource("classpath:templates/" + reportCodeClean + ".xlsx");
        File file = new File(FilenameUtils.normalize(tempPath));
        if (!file.exists()) {
            file.mkdir();
        }
        try (OutputStream out = new FileOutputStream(tempFile);
             InputStream inputStream = resource.getInputStream()) {

            IOUtil.copyCompletely(inputStream, out);
            IReportContentService reportService = getReportService(reportCodeClean);
            workbook = reportService.generate(reportCode, tempFile, dataDate, reportBatchNo, branchCode, false);
//            response.setContentType(String.format("%s;charset=utf-8", "application/x"));
            response.setContentType("application/force-download");
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-disposition", "attachment;filename=" + filename);
            outputStream = response.getOutputStream();
            workbook.write(outputStream);
            outputStream.flush();

        } catch (Exception e) {
            log.error("Error to download report:", e);
            throw e;
        } finally {
            if (workbook != null) {
                try {
                    workbook.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private IReportContentService getReportService(String reportCodeClean) {
        IReportContentService reportService = reportServiceMap.get(reportCodeClean + "ReportService");
        if (reportService == null) {
            reportService = genericReportService;
        }
        return reportService;
    }

    /**
     * 生成Excel报表并转换成HTML
     */
    @GetMapping(value = "/{reportCode}/html")
    public Map<String, Object> convert2Html(@PathVariable String reportCode, @RequestParam String dataDate,
                                            @RequestParam String reportBatchNo, @RequestParam String branchCode,
                                            HttpServletRequest request, HttpServletResponse response) {
        InputStream inputStream = null;
        FileOutputStream out = null;
        try {
            if (StringUtils.isEmpty(reportCode)) {
                throw new RuntimeException("请指定报表");
            }
            //reportCode = FilenameUtils.normalize(reportCode);
            String reportCodeClean = reportCode.replace("-", "").replace("_", "")
                    .replace("(", "").replace(")", "");

            String filename = new String((reportCode + ".xlsx").getBytes("utf-8"), "iso8859-1");

            String key = String.format("report_html_&%s_&%s_&%s_&%s", reportCodeClean, dataDate, reportBatchNo, branchCode);
            //TODO cache
            Map<String, Object> result = null; //(JSONObject) cacheService.get(key);
            if (result == null) {
                //cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/opt/middleware/rwa/rwa.war!/WEB-INF/classes!/templates/G4B2.xlsx
                /*
                //File templateFile = ResourceUtils.getFile("classpath:templates/" + reportCode + ".xlsx");
                ClassPathResource classPathResource = new ClassPathResource("templates/" + reportCodeClean + ".xlsx");
//                InputStream inputStream = classPathResource.getInputStream();

                //生成目标文件
//                File templateFile = File.createTempFile("template_" + System.nanoTime(), ".xlsx");
//                FileUtils.copyInputStreamToFile(inputStream, templateFile);
                 */
                String tempPath = System.getProperty("java.io.tmpdir") + File.separator + "tomcat_" + System.currentTimeMillis();
                File tempFile = new File(FilenameUtils.normalize(tempPath + File.separator + filename));
                Resource resource = new DefaultResourceLoader().getResource("classpath:templates/" + reportCodeClean + ".xlsx");
                File file = new File(FilenameUtils.normalize(tempPath));
                if (!file.exists()) {
                    file.mkdir();
                }
                inputStream = resource.getInputStream();
                out = new FileOutputStream(tempFile);
                IOUtil.copyCompletely(inputStream, out);

                IReportContentService reportService = getReportService(reportCodeClean);
                result = reportService.convert2Html(reportCode, tempFile, dataDate, reportBatchNo, branchCode);
            }
            return result;
        } catch (Exception exp) {
            log.info(reportCode + "生成Excel报表并转换成HTML失败", exp);
            throw new RuntimeException("生成Excel报表并转换成HTML失败(" + exp.getLocalizedMessage() + ")");
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}
